﻿using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using Microsoft.Win32;
using MouseExtender.Logic;
using MouseExtender.Logic.Converters;
using MouseExtender.Logic.Entities;
using MouseExtender.Logic.Enums;
using MouseExtender.Logic.Events;
using MouseExtender.Logic.Helpers;
using MouseExtender.Logic.Managers;
using MouseExtender.Resources;

namespace MouseExtender.Controls.UserControls
{
    public partial class SettingsUC : System.Windows.Controls.UserControl
    {
        private MouseExtenderButton _keys = SettingsManager.CurrentSettings.MouseKeysCombination;
        private System.Windows.Forms.Keys _key = System.Windows.Forms.Keys.None;
        private ModifierKeys _modifier = ModifierKeys.None;

        public SettingsUC()
        {
            InitializeComponent();
        }

        public bool ApplySetting()
        {
            //TODO:use binding and validation rules.
            if (rbManualProxyConfiguration.IsChecked.Value)
            {
                if (string.IsNullOrEmpty(tbHttpProxy.Text) || !Uri.IsWellFormedUriString(tbHttpProxy.Text, UriKind.Absolute))
                {
                    tbHttpProxy.BorderBrush = new SolidColorBrush(Colors.Red);
                    tbHttpProxy.ToolTip = "Http proxy is empty or is not well formatted";
                    return false;
                }
                else
                {
                    tbHttpProxy.BorderBrush = new SolidColorBrush(Colors.Black);
                    tbHttpProxy.ToolTip = null;
                }
            }

            UserSettings settings = SettingsManager.CurrentSettings;
            settings.IconSize = chUseCompactView.IsChecked.Value ? IconSize.Icon16x16 : IconSize.Icon32x32;
            settings.ItemsInRow = (int)slIconsInRow.Value;
            settings.ShowSystemButtonsBar = chShowSystemButtonsBar.IsChecked.Value;
            settings.HideOnMiddleClickWhenOpened = chHideOnMiddleClickWhenOpened.IsChecked ?? false;
            settings.HideCloseButton = chHideCloseButton.IsChecked.Value;
            App.MainWindowInstance.ShowHideCloseButton();
            App.MainWindowInstance.ucSystemButtonsBar.Visibility = settings.ShowSystemButtonsBar == true ? Visibility.Visible : Visibility.Collapsed;
            App.MainWindowInstance.tbtnPin.IsChecked = settings.DontHidePanel = chDontHidePanel.IsChecked.Value;
            settings.CheckUpdatesPeriod = UpdateManager.AutomaticUpdatePeriod = (CheckUpdatesPeriod)(int)slUpdatePeriod.Value;
            settings.MouseKeysCombination = MouseExtenderButtonConverter.ConvertFromString(txtMouseButtonsCombination.Text);
            settings.UseHWAcceleration = chUseHWAcceleration.IsChecked ?? false;

            //internet access settings
            settings.InternetAccessConfigType = (rbAutoDetect.IsChecked ?? false) ?
                InternetAccessConfigurationType.AutoDetect : InternetAccessConfigurationType.Manual;
            settings.HttpProxy = tbHttpProxy.Text;
            settings.UseProxyAuthentication = cbProxyAuthenticationEnabled.IsChecked ?? false;
            settings.ProxyUserName = tbLogin.Text;
            settings.ProxyPassword = tbPassword.Password;
            //keyboard shortcuts
            settings.Key = _key;
            settings.Modifier = _modifier;
            //save settings
            settings.SettingChanged();

            //update environment
            bool isAutostartEnabled = chAutoStart.IsChecked ?? false;
            RegistryKey registryStartupKey = Registry.CurrentUser.OpenSubKey(Constants.RegistryStartupKey, true);
            if (isAutostartEnabled)
            {
                string autoStartCommand = String.Format("\"{0}\" {1}", System.Windows.Forms.Application.ExecutablePath, Constants.AutoStartCommandArg);
                registryStartupKey.SetValue(Constants.RegistryStartupValue, autoStartCommand);
            }
            else
            {
                registryStartupKey.DeleteValue(Constants.RegistryStartupValue, false);
            }

            //update internet proxy
            InternetAccessManager.Initialize();

            return true;
        }

        #region Events Handlers

        private void SettingsUC_Loaded(object sender, RoutedEventArgs e)
        {
            UserSettings settings = SettingsManager.CurrentSettings;
            chUseCompactView.IsChecked = settings.IconSize == IconSize.Icon16x16 || settings.IconSize == default(IconSize);
            lblIconsInRow.Text = settings.ItemsInRow.ToString();
            RegistryKey registryStartupKey = Registry.CurrentUser.OpenSubKey(Constants.RegistryStartupKey, true);
            object startupValue = registryStartupKey.GetValue(Constants.RegistryStartupValue);
            bool isAutostartEnabled = false;
            if (startupValue != null)
                isAutostartEnabled = true;
            chAutoStart.IsChecked = isAutostartEnabled;
            cbExcludedPrograms.ItemsSource = settings.ExcludedPrograms;
            chShowSystemButtonsBar.IsChecked = settings.ShowSystemButtonsBar;
            chHideOnMiddleClickWhenOpened.IsChecked = settings.HideOnMiddleClickWhenOpened;
            chDontHidePanel.IsChecked = settings.DontHidePanel;
            chHideCloseButton.IsChecked = settings.HideCloseButton;
            chUseHWAcceleration.IsChecked = settings.UseHWAcceleration;
            slUpdatePeriod.Value = (int)settings.CheckUpdatesPeriod;
            txtMouseButtonsCombination.Text = MouseExtenderButtonConverter.ConvertToString(settings.MouseKeysCombination);
            chUseCompactView.Focus();

            //internet access settings
            if (settings.InternetAccessConfigType.Value == InternetAccessConfigurationType.AutoDetect)
                rbAutoDetect.IsChecked = true;
            else
                rbManualProxyConfiguration.IsChecked = true;

            tbHttpProxy.Text = settings.HttpProxy;
            cbProxyAuthenticationEnabled.IsChecked = settings.UseProxyAuthentication;
            tbLogin.Text = settings.ProxyUserName;
            tbPassword.Password = settings.ProxyPassword;
            _key = settings.Key;
            _modifier = settings.Modifier;
            if (_key == System.Windows.Forms.Keys.None)
            {
                txtKeyboardShortcut.Text = "None";
            }
            else
            {
                txtKeyboardShortcut.Text = (settings.Modifier == ModifierKeys.None ? String.Empty : settings.Modifier.ToString() + "+") + _key.ToString();
            }
        }

        #endregion

        private void btnAddExcludedProgram_Click(object sender, RoutedEventArgs e)
        {
            using (ControlHide hidePopup = new ControlHide(this))
            {
                RunningProgramsUC programs = null;
                PopupUC addExcluded = new PopupUC();
                programs = new RunningProgramsUC();
                programs.RunningProgramSelected += new LaunchItemSelected((o, args) =>
                    {
                        UserSettings settings = SettingsManager.CurrentSettings;
                        settings.AddExcludedProgram(args.LauncherItem.LaunchPath.ToUpper());
                        addExcluded.IsOpen = false;
                        ((UIElement)this.Parent).Visibility = Visibility.Visible;
                        App.MainWindowInstance.grid.Children.Remove(addExcluded);
                    }
                );

                programs.Closed += new EventHandler((o, args) =>
                    {
                        addExcluded.IsOpen = false;
                        ((UIElement)this.Parent).Visibility = Visibility.Visible;
                        App.MainWindowInstance.grid.Children.Remove(addExcluded);
                    }
                );

                addExcluded.placeholder.Child = programs;
                App.MainWindowInstance.grid.Children.Add(addExcluded);
                programs.Refresh();
                programs.ShowBrowseMore = true;
                ((UIElement)this.Parent).Visibility = Visibility.Hidden;
                addExcluded.IsOpen = true;
            }
        }

        private void btnRemoveExcludedProgram_Click(object sender, RoutedEventArgs e)
        {
            ExcludedProgram programToRemove = cbExcludedPrograms.SelectedItem as ExcludedProgram;
            if (programToRemove != null)
            {
                SettingsManager.CurrentSettings.ExcludedPrograms.Remove(programToRemove);
            }
        }

        private void txtMouseButtonsCombination_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            e.Handled = true;
            txtMouseButtonsCombination.Style = (Style)Resources["Default"];
            MouseExtenderButton buttonsCombination = MouseExtenderButton.None;

            switch (e.ChangedButton)
            {
                case System.Windows.Input.MouseButton.Left:
                    buttonsCombination = MouseExtenderButton.LeftButton;
                    break;
                case System.Windows.Input.MouseButton.Middle:
                    buttonsCombination = MouseExtenderButton.MiddleButton;
                    break;
                case System.Windows.Input.MouseButton.Right:
                    buttonsCombination = MouseExtenderButton.RightButton;
                    break;
                case System.Windows.Input.MouseButton.XButton1:
                    buttonsCombination = MouseExtenderButton.XButton1;
                    break;
                case System.Windows.Input.MouseButton.XButton2:
                    buttonsCombination = MouseExtenderButton.XButton2;
                    break;
                default:
                    buttonsCombination = MouseExtenderButton.MiddleButton;
                    break;
            }

            ModifierKeys keys = Win32Helper.GetModifierKeys();
            if ((keys & ModifierKeys.Control) == ModifierKeys.Control)
                buttonsCombination |= MouseExtenderButton.CtrlKey;
            if ((keys & ModifierKeys.Alt) == ModifierKeys.Alt)
                buttonsCombination |= MouseExtenderButton.AltKey;
            if ((keys & ModifierKeys.Shift) == ModifierKeys.Shift)
                buttonsCombination |= MouseExtenderButton.ShiftKey;

            bool isLeft = (buttonsCombination & MouseExtenderButton.LeftButton) == MouseExtenderButton.LeftButton;
            bool isRight = (buttonsCombination & MouseExtenderButton.RightButton) == MouseExtenderButton.RightButton;
            bool isNoKey = keys == ModifierKeys.None || keys == ModifierKeys.Windows;
            if ((isLeft || isRight) && isNoKey)
            {
                txtMouseButtonsCombination.Text = UIResources.Settings_MouseConfigurationInavlid;
                return;
            }
            _keys = buttonsCombination;
            txtMouseButtonsCombination.Text = MouseExtenderButtonConverter.ConvertToString(buttonsCombination);
        }

        private void txtMouseButtonsCombination_MouseEnter(object sender, MouseEventArgs e)
        {
            txtMouseButtonsCombination.Text = UIResources.Settings_MouseConfigurationMessage;
            txtMouseButtonsCombination.Style = (Style)Resources["WaterMark"];
        }

        private void txtMouseButtonsCombination_MouseLeave(object sender, MouseEventArgs e)
        {
            txtMouseButtonsCombination.Text = MouseExtenderButtonConverter.ConvertToString(_keys);
            txtMouseButtonsCombination.Style = (Style)Resources["Default"];
        }

        private void txtKeyboardShortcut_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            e.Handled = true;

            if (e.Key == Key.LeftCtrl ||
                e.Key == Key.RightCtrl ||
                e.Key == Key.LeftAlt ||
                e.Key == Key.RightAlt ||
                e.Key == Key.LeftShift ||
                e.Key == Key.RightShift)
                return;

            _key = (System.Windows.Forms.Keys)KeyInterop.VirtualKeyFromKey(e.Key);
            var keyName = e.Key.ToString();
            _modifier = ModifierKeys.None;
            string shortcutText = "";
            if (e.Key == Key.System)
            {
                _key = (System.Windows.Forms.Keys)KeyInterop.VirtualKeyFromKey(e.SystemKey);
                keyName = e.SystemKey.ToString();
            }
            if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
            {
                _modifier = ModifierKeys.Control;
                shortcutText += "Ctrl+";
            }
            if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
            {
                _modifier = ModifierKeys.Shift;
                shortcutText += "Shift+";
            }
            if ((Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt)
            {
                _modifier = ModifierKeys.Alt;
                shortcutText += "Alt+";
            }
            txtKeyboardShortcut.Text = shortcutText + keyName;
        }
    }
}
